#******************************************************************************
#******************************************************************************`

# standard libraries

import random as rand

# from numpy.testing import assert_allclose

# local libraries

import numpy as np

from src.hyhetra.pipes.classes import StandardisedPipe, StandardisedPipeDatabase

from src.hyhetra.pipes.twin import InsulatedTwinPipe, StandardisedTwinPipe

import src.hyhetra.pipes.fic as fic

# import src.hyhetra.common.core as hht_core

# from src.hyhetra.common.core import ConvectionHeatTransferCoefficient

from src.hyhetra.common.factors import shape_factor_buried_horizontal_isothermal_cylinder

from src.hyhetra.common.factors import thermal_resistance_from_shape_factor

import src.hyhetra.pipes.trenches as trenches

from src.hyhetra.pipes.trenches import zero_transmission_efficiency_trench_length

#******************************************************************************
#******************************************************************************

def examples(fluiddb: fic.FluidDatabase, 
             singlepipedb: StandardisedPipeDatabase, 
             twinpipedb: StandardisedPipeDatabase):
    
    # # get water properties' database
    
    # fluiddata_file = 'data/fluids/water/incropera2006_saturated_water.csv'

    # fluiddb = fic.FluidDatabase(fluid='fluid', phase='l', source=fluiddata_file)
    
    # # pipe database

    # list_pipedb_files = ['/interesting_folder/hyhetra/pipes/singlepipes_s1.csv',
    #                      #'/interesting_folder/hyhetra/pipes/singlepipes_s2.csv',
    #                      #'/interesting_folder/hyhetra/pipes/singlepipes_s3.csv'
    #                      ]

    # pipedb = StandardisedPipeDatabase(source=list_pipedb_files)
    
    # examples
    
    example_zero_transmission_efficiency()
    
    example_bohm2000_system1_conventional(fluiddb)
    
    example_bohm2000_system1_new(fluiddb)
    
    example_bohm2000_system2(fluiddb)
    
    example_bohm2000_system2_wallenten(fluiddb)
    
    example_bohm2000_system3(fluiddb)
    
    example_bohm2000_system3_wallenten(fluiddb)
    
    example_sven2013(fluiddb,[])
    
    example_fic(fluiddb)
    
    example_heating_cooling_single_pipe_trench_obj(fluiddb, singlepipedb)
    
    example_heating_cooling_twin_pipe_trench_obj(fluiddb, twinpipedb)
    
    example_bohm2005_distribution_pipes_single(fluiddb)
    
    example_bohm2005_distribution_pipes_twin(fluiddb)
    
    example_unknown_models()
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_heating_cooling_twin_pipe_trench_obj(fluid_db, pipe_db):

    #**************************************************************************
    #**************************************************************************
    
    # create list of pipe objects
    
    # create distric heating trench object
    
    list_pipe_tuples = [tuple_entry for tuple_entry in pipe_db.pipe_tuples]
    
    list_pipe_tuples = list_pipe_tuples[1:3]

    #**************************************************************************
    #**************************************************************************
    
    # time span
    
    number_time_intervals = 3
    
    time_interval_duration = [rand.random() 
                              for t in range(number_time_intervals)]
    
    # network

    dhn_supply_temperature = 80+273.15 # K

    dhn_return_temperature = 50+273.15 # K

    dhn_max_specific_pressure_loss = 100 # Pa
    
    dcn_supply_temperature = 6+273.15
    
    dcn_return_temperature = 12+273.15

    # trench

    trench_pipe_depth = 3

    trench_pipe_distance = 1.5 #

    trench_ground_thermal_conductivity = 0.5
    
    trench_h_ground_air = 14.6

    trench_ground_surface_temperature = [
        10+273.15 # K
        for k in range(number_time_intervals)] 

    # pipe details

    pipe_length = 1298

    pipe_relative_roughness = 5e-5

    #**************************************************************************
    #**************************************************************************

    list_pipes = [
        StandardisedTwinPipe(length=pipe_length,
                          pipe_tuple=pipe_tuple,
                          e_rel=pipe_relative_roughness,
                          db=pipe_db)
        for i, pipe_tuple in enumerate(list_pipe_tuples)
        ]
    
    #**************************************************************************
    #**************************************************************************
    
    # create district heating trench object
    
    dht_one = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=[list_pipes[0]],
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)  

    #**************************************************************************
    #**************************************************************************
    
    # create district heating trench object
    
    dht = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)    
    
    #**************************************************************************
    #**************************************************************************

    # create district heating trench object (using an indicative fluid speed)
    
    dht_ifs = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature, 
        reference_heat_flow_rate=1e3)     

    #**************************************************************************
    #**************************************************************************

    # create district cooling trench object
    
    dct_one = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=[list_pipes[0]],
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dcn_supply_temperature, 
        return_temperature=dcn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature) 

    #**************************************************************************
    #**************************************************************************

    # create district cooling trench object
    
    dct = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dcn_supply_temperature, 
        return_temperature=dcn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)     

    #**************************************************************************
    #**************************************************************************

    # create district cooling trench object (using an indicative fluid speed)
    
    dct_ifs = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dcn_supply_temperature, 
        return_temperature=dcn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature, 
        reference_heat_flow_rate=1e3)     
    
    #**************************************************************************
    #**************************************************************************
    
    pipe_relative_roughness = 0

    #**************************************************************************
    #**************************************************************************

    list_pipes = [
        StandardisedTwinPipe(length=pipe_length,
                          pipe_tuple=pipe_tuple,
                          e_rel=pipe_relative_roughness,
                          db=pipe_db)
        for i, pipe_tuple in enumerate(list_pipe_tuples)
        ]
    
    #**************************************************************************
    #**************************************************************************
    
    # create district heating trench object (smooth pipes)
    
    dht_smooth = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)   

    #**************************************************************************
    #**************************************************************************
    
    # create district heating trench object (stagnation)
    
    dht_stagnation = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature,
        reference_heat_flow_rate=0)    

    #**************************************************************************
    #**************************************************************************
    
    # create district heating trench object (multiple pipe depths)
    
    dht_multi_pipe_depths = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=[
            pipe.d_cas for pipe in list_pipes], 
        pipe_center_distance=None, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)    

    #**************************************************************************
    #**************************************************************************
    
    # test using an incorrect pipe object
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=60,
                             e_eff=1e-5,
                             d_int=0.0889-2*0.0032,
                             d_ext=0.0889,
                             d_ins=0.1578,
                             d_cas=0.160,
                             k_ins=0.0265,
                             k_cas=0.43)
    
    try:
        dht_one = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
            pipes=[pipe],
            fluid_database=fluid_db, 
            ground_thermal_conductivity=trench_ground_thermal_conductivity, 
            ground_air_heat_transfer_coefficient=trench_h_ground_air, 
            pipe_center_depth=trench_pipe_depth, 
            pipe_center_distance=trench_pipe_distance, 
            supply_temperature=dhn_supply_temperature, 
            return_temperature=dhn_return_temperature, 
            max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
            time_interval_duration=time_interval_duration, 
            surroundings_temperature=trench_ground_surface_temperature)  
    except AssertionError:
        assert True

    #**************************************************************************
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_zero_transmission_efficiency():
    
    design_heat_transfer_index = 0
    specific_heat_gain_or_loss_index = 1
    network_polarity_index = 2
    heat_gain_loss_polarity_index = 3
    isfinite_index = 4
    
    #**************************************************************************
    
    # 16 cases and their result
    
    truth_table = [
        [ 3,  1, True,   True,   True],  # heating grid with losses: finite 
        [ 3, -1, True,   False,  True],  # heating grid with losses: finite 
        [-3,  1, False,  True,   True],  # heating grid with losses: finite 
        [-3, -1, False,  False,  True],  # heating grid with losses: finite 
        
        [-3,  1, True,   True,   False], # cooling grid with losses: infinite 
        [-3, -1, True,   False,  False], # cooling grid with losses: infinite 
        [ 3,  1, False,  True,   False], # cooling grid with losses: infinite 
        [ 3, -1, False,  False,  False], # cooling grid with losses: infinite 
        
        [ 3, -1, True,   True,   False],  # heating grid with gains: infinite 
        [ 3,  1, True,   False,  False],  # heating grid with gains: infinite 
        [-3, -1, False,  True,   False],  # heating grid with gains: infinite 
        [-3,  1, False,  False,  False],  # heating grid with gains: infinite 
        
        [-3, -1, True,   True,   True],  # cooling grid with gains: finite 
        [-3,  1, True,   False,  True],  # cooling grid with gains: finite 
        [ 3, -1, False,  True,   True],  # cooling grid with gains: finite 
        [ 3,  1, False,  False,  True],  # cooling grid with gains: finite 
        ]
    
    #**************************************************************************
    
    for case in truth_table:
        
        max_pipe_length = zero_transmission_efficiency_trench_length(
            design_trench_heat_transfer_rate=case[design_heat_transfer_index],
            specific_trench_gains_or_losses=case[specific_heat_gain_or_loss_index],
            heating_network_rates_are_positive=case[network_polarity_index],
            fluid_heat_losses_are_positive=case[heat_gain_loss_polarity_index]
            )
        
        assert max_pipe_length > 0
        
        if case[isfinite_index]:
        
            assert np.isfinite(max_pipe_length)
            
        else:
            
            assert not np.isfinite(max_pipe_length)
    
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_heating_cooling_single_pipe_trench_obj(fluid_db, pipe_db):

    #**************************************************************************
    #**************************************************************************
    
    # create list of pipe objects
    
    # create distric heating trench object
    
    list_pipe_tuples = [tuple_entry for tuple_entry in pipe_db.pipe_tuples]
    
    list_pipe_tuples = list_pipe_tuples[1:3]

    #**************************************************************************
    #**************************************************************************
    
    # time span
    
    number_time_intervals = 3
    
    time_interval_duration = [rand.random() 
                              for t in range(number_time_intervals)]
    
    # network

    dhn_supply_temperature = 80+273.15 # K

    dhn_return_temperature = 50+273.15 # K

    dhn_max_specific_pressure_loss = 100 # Pa
    
    dcn_supply_temperature = 6+273.15
    
    dcn_return_temperature = 12+273.15

    # trench

    trench_pipe_depth = 3

    trench_pipe_distance = 1.5 #

    trench_ground_thermal_conductivity = 0.5
    
    trench_h_ground_air = 14.6

    trench_ground_surface_temperature = [
        10+273.15 # K
        for k in range(number_time_intervals)] 

    # pipe details

    pipe_length = 1298

    pipe_relative_roughness = 5e-5

    #**************************************************************************
    #**************************************************************************

    list_pipes = [
        StandardisedPipe(length=pipe_length,
                          pipe_tuple=pipe_tuple,
                          e_rel=pipe_relative_roughness,
                          db=pipe_db)
        for i, pipe_tuple in enumerate(list_pipe_tuples)
        ]

    #**************************************************************************
    #**************************************************************************
    
    # create district heating trench object
    
    dht = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)   
    
    #**************************************************************************
    #**************************************************************************

    # create district heating trench object (using an indicative fluid speed)
    
    dht_ifs = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dhn_supply_temperature, 
        return_temperature=dhn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature, 
        reference_heat_flow_rate=1e3)     
    
    #**************************************************************************
    #**************************************************************************

    # create district cooling trench object
    
    dct = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dcn_supply_temperature, 
        return_temperature=dcn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)  
    
    #**************************************************************************
    #**************************************************************************

    # create district cooling trench object (using an indicative fluid speed)
    
    dct_ifs = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=trench_pipe_depth, 
        pipe_center_distance=trench_pipe_distance, 
        supply_temperature=dcn_supply_temperature, 
        return_temperature=dcn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature, 
        reference_heat_flow_rate=1e3)     
    
    #**************************************************************************
    #**************************************************************************
    
    # make sure the reference heat flow rate level provided made a difference
    
    for i, pipe in enumerate(list_pipes):
        
        for t in range(number_time_intervals):
        
            assert (
                dht.heat_transfer_return[i][t] != 
                dht_ifs.heat_transfer_return[i][t])
                
            assert (
                dht.heat_transfer_supply[i][t] != 
                dht_ifs.heat_transfer_supply[i][t])
                
            assert (
                dct.heat_transfer_return[i][t] != 
                dct_ifs.heat_transfer_return[i][t])
                
            assert (
                dct.heat_transfer_supply[i][t] != 
                dct_ifs.heat_transfer_supply[i][t])
            
    
    # print(dht.zero_transmission_efficiency_trench_length())
    
    # print(dht_ifs.zero_transmission_efficiency_trench_length())
    
    # print(dct.zero_transmission_efficiency_trench_length())
    
    # print(dct_ifs.zero_transmission_efficiency_trench_length())

    #**************************************************************************
    #**************************************************************************

    # create district cooling trench object (single pipes, different distances)
    
    dct_different_dists = trenches.SupplyReturnPipeTrenchWithIdenticalPipes(
        pipes=list_pipes,
        fluid_database=fluid_db, 
        ground_thermal_conductivity=trench_ground_thermal_conductivity, 
        ground_air_heat_transfer_coefficient=trench_h_ground_air, 
        pipe_center_depth=[
            pipe.d_cas for pipe in list_pipes], 
        pipe_center_distance=[
            pipe.d_cas*1.1 for pipe in list_pipes],  
        supply_temperature=dcn_supply_temperature, 
        return_temperature=dcn_return_temperature, 
        max_specific_pressure_loss=dhn_max_specific_pressure_loss, 
        time_interval_duration=time_interval_duration, 
        surroundings_temperature=trench_ground_surface_temperature)  

    #**************************************************************************
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2000_system1_conventional(fluiddb):
    
    #**************************************************************************
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=55,
                             e_eff=1e-5,
                             d_int=0.273-2*0.005,
                             d_ext=0.273,
                             d_ins=0.273,
                             d_cas=0.273,
                             k_ins=0.029,
                             k_cas=0.5)
    
    fluid_temperature = 25+273.15
    
    # # fluid database
    
    # fluiddata_file = '/interesting_folder/hyhetra/fluids/water/incropera2006_saturated_water.csv'

    # fluiddb = fic.FluidDatabase(fluid='fluid', phase='l', source=fluiddata_file)
    
    # fluid
    
    fluid = fic.Fluid(phase='l',
                      temperature=fluid_temperature,
                      pressure=1e5,
                      db=fluiddb)
    
    # trench
    
    pipe_depth = 0.75 # m
    
    ground_temperature = 7.8+273.15 # K
    
    h_gs = 14.6 # W/m2K
    
    list_soil_k = [0.9, 2.7] # W/mK
    
    #**************************************************************************
    
    list_u1_true = [2.294, 6.500] # W/m
    
    list_q_true = [39.5, 111.8] # W/m
    
    relative_tolerance = 0.01 # Max relative difference: 0.0057026
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):

        #**********************************************************************
        
        # calculations
        
        conduction_factor = shape_factor_buried_horizontal_isothermal_cylinder(
            pipe.d_cas,
            1,
            pipe_depth+soil_k/h_gs)
        
        extra_specific_resistance = thermal_resistance_from_shape_factor(
            conduction_factor,
            soil_k)
        
        r_line = fic.InsulatedPipeSpecificResistance(
            h_internal=np.inf,
            h_external=np.inf, 
            extra_specific_resistance=extra_specific_resistance, 
            pipe=pipe)
        
        q = (fluid.temperature-ground_temperature)/r_line
                
        #**********************************************************************
        
        np.testing.assert_allclose(q, 
                                   list_q_true[i],
                                   rtol=relative_tolerance)
    
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2000_system1_new(fluiddb):
    
    #**************************************************************************
    
    # heat capacities:
    # PUR: 153 kJ/m3K
    # PEH: 2200 kJ/m3K
    # steel: 3785 kJ/m3K
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=60,
                             e_eff=1e-5,
                             d_int=0.273-2*0.005,
                             d_ext=0.273,
                             d_ins=0.273,
                             d_cas=0.273,
                             k_ins=0.029,
                             k_cas=0.43)
    
    fluid_temperature = 25+273.15
    
    # # fluid database
    
    # fluiddata_file = '/interesting_folder/hyhetra/fluids/water/incropera2006_saturated_water.csv'

    # fluiddb = fic.FluidDatabase(fluid='fluid', phase='l', source=fluiddata_file)
    
    # fluid
    
    fluid = fic.Fluid(phase='l',
                      temperature=fluid_temperature,
                      pressure=1e5,
                      db=fluiddb)
    
    # trench
    
    pipe_depth = 0.75 # m
    
    ground_temperature = 7.8+273.15 # K
    
    h_gs = 14.6 # W/m2K
    
    list_soil_k = [0.9, 2.7] # W/mK
    
    #**************************************************************************
    
    list_u1_true = [2.294, 6.500] # W/m
    
    list_q_true = [39.5, 111.8] # W/m
    
    relative_tolerance = 0.01 # Max relative difference obtained: 0.00461398
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):

        #**********************************************************************
        
        # calculations
        
        pipe_depth_modified = pipe_depth+(soil_k/h_gs)
        
        r_g = (
            np.log(4*pipe_depth_modified/pipe.d_cas)/
            (2*np.pi*soil_k)
            )
        
        r_i = fic.InsulatedPipeSpecificResistance(
            h_internal=np.inf,
            h_external=np.inf, 
            extra_specific_resistance=0, 
            pipe=pipe)
        
        u1 = 1/(r_g+r_i)
        
        q = (fluid.temperature-ground_temperature)*u1
                
        #**********************************************************************
        
        np.testing.assert_allclose(u1, 
                                   list_u1_true[i],
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(q, 
                                   list_q_true[i],
                                   rtol=relative_tolerance)
    
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2000_system2(fluiddb):
    
    #**************************************************************************
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                              k=60,
                              e_eff=1e-5,
                              d_int=0.273-2*0.005,
                              d_ext=0.273,
                              d_ins=0.3904, #0.400-2*0.005,
                              d_cas=0.400,
                              k_ins=0.029,
                              k_cas=0.43)
    
    fluid_temperature = 120+273.15
    
    # # fluid database
    
    # fluiddata_file = '/interesting_folder/hyhetra/fluids/water/incropera2006_saturated_water.csv'

    # fluiddb = fic.FluidDatabase(fluid='fluid', phase='l', source=fluiddata_file)
    
    # fluid
    
    fluid = fic.Fluid(phase='l',
                      temperature=fluid_temperature,
                      pressure=1e5,
                      db=fluiddb)
    
    # trench
    
    pipe_depth = 0.75 # m
    
    ground_temperature = 7.8+273.15 # K
    
    h_gs = 14.6 # W/m2K
    
    list_soil_k = [0.9, 2.7] # W/mK
    
    #**************************************************************************
    
    list_u1_true = [0.434, 0.484] # W/m
    
    list_q_true = [48.7, 54.4] # W/m
    
    relative_tolerance = 0.02 # 0.088 is the lowest that can be reasonably obtained
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):

        #**********************************************************************
        
        # calculations
        
        pipe_depth_modified = pipe_depth+(soil_k/h_gs)
        
        r_g = (
            np.log(4*pipe_depth_modified/pipe.d_cas)/
            (2*np.pi*soil_k)
            )
        
        r_i = fic.InsulatedPipeSpecificResistance(
            h_internal=np.inf,
            h_external=np.inf, 
            extra_specific_resistance=0, 
            pipe=pipe)
        
        u1 = 1/(r_g+r_i)
        
        q = (fluid.temperature-ground_temperature)*u1
                
        #**********************************************************************
        
        np.testing.assert_allclose(u1, 
                                   list_u1_true[i],
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(q, 
                                   list_q_true[i],
                                   rtol=relative_tolerance)
    
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2000_system2_wallenten(fluiddb):
    
    #**************************************************************************
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                              k=60,
                              e_eff=1e-5,
                              d_int=0.273-2*0.005,
                              d_ext=0.273,
                              d_ins=0.3904, #0.400-2*0.005,
                              d_cas=0.400,
                              k_ins=0.029,
                              k_cas=0.43)
    
    fluid_temperature = 120+273.15
    
    # fluid
    
    fluid = fic.Fluid(phase='l',
                      temperature=fluid_temperature,
                      pressure=1e5,
                      db=fluiddb)
    
    # trench
    
    pipe_depth = 0.75 # m
    
    ground_temperature = 7.8+273.15 # K
    
    h_gs = 14.6 # W/m2K
    
    list_soil_k = [0.9, 2.7] # W/mK
    
    #**************************************************************************
    
    list_u1_true = [0.434, 0.484] # W/m
    
    list_q_true = [48.7, 54.4] # W/m
    
    relative_tolerance = 0.075 # 0.088 is the lowest that can be reasonably obtained
    
    #**************************************************************************
    
    # TRGTPT_MULTIPOLE_SECOND_ORDER
    
    for i, soil_k in enumerate(list_soil_k):

        #**********************************************************************
        
        # calculations
        
        r_g = trenches.ThermalResistanceBuriedSinglePipeWallenten(
            pipe,
            soil_k,
            pipe_depth,
            h_gs,
            model=trenches.TRGTPT_MULTIPOLE_SECOND_ORDER)
        
        u1 = 1/r_g
        
        q = (fluid.temperature-ground_temperature)*u1
                
        #**********************************************************************
        
        np.testing.assert_allclose(u1, 
                                   list_u1_true[i],
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(q, 
                                   list_q_true[i],
                                   rtol=relative_tolerance)
    
    #**************************************************************************
    
    # TRGTPT_MULTIPOLE_ZERO_ORDER
    
    relative_tolerance = 0.075 # 0.088 is the lowest that can be reasonably obtained
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):

        #**********************************************************************
        
        # calculations
        
        r_g = trenches.ThermalResistanceBuriedSinglePipeWallenten(
            pipe,
            soil_k,
            pipe_depth,
            h_gs,
            model=trenches.TRGTPT_MULTIPOLE_ZERO_ORDER)
        
        u1 = 1/r_g
        
        q = (fluid.temperature-ground_temperature)*u1
                
        #**********************************************************************
        
        np.testing.assert_allclose(u1, 
                                   list_u1_true[i],
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(q, 
                                   list_q_true[i],
                                   rtol=relative_tolerance)
    
    #**************************************************************************
    
    # TRGTPT_MULTIPOLE_FIRST_ORDER
    
    relative_tolerance = 0.075
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):

        #**********************************************************************
        
        # calculations
        
        r_g = trenches.ThermalResistanceBuriedSinglePipeWallenten(
            pipe,
            soil_k,
            pipe_depth,
            h_gs,
            model=trenches.TRGTPT_MULTIPOLE_FIRST_ORDER)
        
        u1 = 1/r_g
        
        q = (fluid.temperature-ground_temperature)*u1
                
        #**********************************************************************
        
        np.testing.assert_allclose(u1, 
                                   list_u1_true[i],
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(q, 
                                   list_q_true[i],
                                   rtol=relative_tolerance)
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2000_system3(fluiddb):
    
    #**************************************************************************
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                              k=60,
                              e_eff=1e-5,
                              d_int=0.273-2*0.005,
                              d_ext=0.273,
                              d_ins=0.3904, #0.400-2*0.005,
                              d_cas=0.400,
                              k_ins=0.029,
                              k_cas=0.43)
    
    supply_temperature = 100+273.15
    
    return_temperature = 60+273.15
    
    # # fluid database
    
    # fluiddata_file = 'data/fluids/water/incropera2006_saturated_water.csv'
    
    # fluiddb = fic.FluidDatabase(fluid='fluid', phase='l', source=fluiddata_file)
        
    # trench
    
    pipe_distance = 0.73 # m
    
    pipe_depth = 1.28 # m
    
    ground_temperature = 7.8+273.15 # K
    
    h_gs = 14.6 # W/m2K
    
    list_soil_k = [0.9, 2.7] # W/mK
    
    #**************************************************************************
    
    list_u1_true = [0.422, 0.479] # W/m
    
    list_u2_true = [0.042, 0.019] # W/m
    
    list_qs_true = [36.7, 43.2] # W/m
    
    list_qr_true = [18.2, 23.2] # W/m
    
    list_model = [trenches.TRGTPT_KRISCHER1936,
                  trenches.TRGTPT_MULTIPOLE_ZERO_ORDER,
                  trenches.TRGTPT_MULTIPOLE_FIRST_ORDER]
    
    # tolerances per model
    
    list_relative_tolerance = [0.0375,
                               0.0383,
                               0.0480]
    
    #**************************************************************************
    
    for j, model in enumerate(list_model):
        
        #**********************************************************************
    
        for i, soil_k in enumerate(list_soil_k):
    
            #******************************************************************
            
            # calculations
            
            (u1, 
             u2,
             _,
             _,
             _) = trenches.HeatTransferCoefficientsTwoBuriedSingles(
                pipe,
                pipe_depth,
                pipe_distance,
                soil_k,
                h_gs,
                np.inf,
                model=model)
                 
                      
            qs, qr = trenches.HeatLossesBuriedSupplyReturnPipesDirect(
                supply_temperature,
                return_temperature,
                ground_temperature,
                u1, 
                u2)
                        
            #******************************************************************
            
            np.testing.assert_allclose(u1, 
                                        list_u1_true[i],
                                        rtol=list_relative_tolerance[j])
                                       
            np.testing.assert_allclose(u2, 
                                        list_u2_true[i],
                                        rtol=list_relative_tolerance[j])
                                       
            np.testing.assert_allclose(qs, 
                                       list_qs_true[i],
                                       rtol=list_relative_tolerance[j])
                                        
            np.testing.assert_allclose(qr, 
                                       list_qr_true[i],
                                       rtol=list_relative_tolerance[j])
        
        #**********************************************************************
        
    #**************************************************************************
    
    # TODO: test the class definitions for trenches
    
    #**************************************************************************
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2000_system3_wallenten(fluiddb):
    
    #**************************************************************************
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                              k=60,
                              e_eff=1e-5,
                              d_int=0.273-2*0.005,
                              d_ext=0.273,
                              d_ins=0.3904, #0.400-2*0.005,
                              d_cas=0.400,
                              k_ins=0.029,
                              k_cas=0.43)
    
    supply_temperature = 100+273.15
    
    return_temperature = 60+273.15
    
    # # fluid database
    
    # fluiddata_file = 'data/fluids/water/incropera2006_saturated_water.csv'
    
    # fluiddb = fic.FluidDatabase(fluid='fluid', phase='l', source=fluiddata_file)
    
    # fluid, supply
    
    fluid_supply = fic.Fluid(phase='l',
                             temperature=supply_temperature,
                             pressure=1e5,
                             db=fluiddb)
                             
    # fluid, return
    
    fluid_return = fic.Fluid(phase='l',
                             temperature=return_temperature,
                             pressure=1e5,
                             db=fluiddb)
    
    # trench
    
    pipe_distance = 0.73 # m
    
    pipe_depth = 1.28 # m
    
    ground_temperature = 7.8+273.15 # K
    
    h_gs = 14.6 # W/m2K
    
    list_soil_k = [0.9, 2.7] # W/mK
    
    #**************************************************************************
    
    list_u1_true = [0.422, 0.479] # W/m
    
    list_u2_true = [0.042, 0.019] # W/m
    
    list_qs_true = [36.7, 43.2] # W/m
    
    list_qr_true = [18.2, 23.2] # W/m
    
    relative_tolerance = 0.1 # 0.088 is the lowest that can be reasonably obtained
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):
    
        #**********************************************************************
        
        # calculations
        
        (rsym,
         rasym) = trenches.ThermalResistanceTwoBuriedSinglePipesWallenten(
            pipe,
            soil_k,
            pipe_depth,
            pipe_distance,
            h_gs,
            model=trenches.TRGTPT_MULTIPOLE_FIRST_ORDER)
        
        # qs = (
        #     ((supply_temperature+return_temperature)/2-ground_temperature)/rsym
        #     +
        #     ((supply_temperature-return_temperature)/2)/rasym
        #     )
        
        # qr = (
        #     ((supply_temperature+return_temperature)/2-ground_temperature)/rsym
        #     -
        #     ((supply_temperature-return_temperature)/2)/rasym
        #     )
                     
        (qs,
         qr) = trenches.HeatLossesSupplyReturnPipesSymmetricalAntiSymmetrical(
            supply_temperature,
            return_temperature,
            ground_temperature,
            rsym,
            rasym)
                    
        #**********************************************************************
        
        # np.testing.assert_allclose(u1, 
        #                            list_u1_true[i],
        #                            rtol=relative_tolerance)
                                   
        # np.testing.assert_allclose(u2, 
        #                            list_u2_true[i],
        #                            rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(qs, 
                                   list_qs_true[i],
                                   rtol=relative_tolerance)
                                    
        np.testing.assert_allclose(qr, 
                                   list_qr_true[i],
                                   rtol=relative_tolerance)
    
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_sven2013(fluiddb, pipedb):
    
    #**************************************************************************
    
    # Sven2013, page 80
    
    # pipe (DN150, insulation class III)
    
    # source: Sven2013, page 320
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=np.inf,
                             e_eff=0.01/1000, #0.01 mm
                             d_int=0.1683,#-4/1000,
                             d_ext=0.1683,
                             d_ins=0.315-4.1/1000, 
                             d_cas=0.315,
                             k_ins=0.03,
                             k_cas=np.inf)
    
    supply_temperature = 85+273.15
    
    return_temperature = 45+273.15
    
    outdoor_temperature = 6+273.15 # K
    
    # trench
    
    pipe_distance = 0.52 # m
    
    pipe_depth = 0.66 # m
    
    h_gs = np.inf # 14.6 # W/m2K
    
    list_soil_k = [1.5] # W/mK
    
    #**************************************************************************
    
    list_rg_true = [0.12] # m2K/W
    
    list_ri_true = [1.8] # m2K/W
    
    list_rm_true = [0.06] # m2K/W
    
    list_qs_true = [20.4] # W/m
    
    list_qr_true = [9.6] # W/m
    
    list_q_true = [30.0] # W/m
    
    relative_tolerance = 0.08 # 0.07537929 is the minimum
    
    #**************************************************************************
    
    for i, soil_k in enumerate(list_soil_k):
    
        #**********************************************************************
        
        # method 1
        
        (rsym,
         rasym) = trenches.ThermalResistanceTwoBuriedSinglePipesWallenten(
            pipe,
            soil_k,
            pipe_depth,
            pipe_distance,
            h_gs,
            model=trenches.TRGTPT_MULTIPOLE_ZERO_ORDER)
        
        # qs = (
        #     ((supply_temperature+return_temperature)/2-outdoor_temperature)/rsym
        #     +
        #     ((supply_temperature-return_temperature)/2)/rasym
        #     )
        
        # qr = (
        #     ((supply_temperature+return_temperature)/2-outdoor_temperature)/rsym
        #     -
        #     ((supply_temperature-return_temperature)/2)/rasym
        #     )
             
        (qs,
         qr) = trenches.HeatLossesSupplyReturnPipesSymmetricalAntiSymmetrical(
            supply_temperature,
            return_temperature,
            outdoor_temperature,
            rsym,
            rasym)
                    
        #**********************************************************************
                           
        np.testing.assert_allclose(qs, 
                                   list_qs_true[i],
                                   rtol=relative_tolerance)
                                    
        np.testing.assert_allclose(qr, 
                                   list_qr_true[i],
                                   rtol=relative_tolerance)
                                           
        #**********************************************************************
        
    #**************************************************************************
    
    relative_tolerance = 0.1
    
    for i, soil_k in enumerate(list_soil_k):
    
        #**********************************************************************
        
        # method 2
        
        (u1, 
         u2,
         r_g,
         r_i,
         r_m) = trenches.HeatTransferCoefficientsTwoBuriedSingles(
            pipe,
            pipe_depth,
            pipe_distance,
            soil_k,
            h_gs,
            np.inf,
            model=trenches.TRGTPT_MULTIPOLE_ZERO_ORDER)
               
                      
        qs, qr = trenches.HeatLossesBuriedSupplyReturnPipesDirect(
            supply_temperature,
            return_temperature,
            outdoor_temperature,
            u1, 
            u2)
             
        #**********************************************************************
                                                 
        # np.testing.assert_allclose(qs+qr, 
        #                             list_q_true[i],
        #                             rtol=relative_tolerance)
                                                   
        np.testing.assert_allclose(r_g, 
                                   list_rg_true[i]/(pipe.d_int*np.pi),
                                   rtol=relative_tolerance)
                               
        np.testing.assert_allclose(r_m, 
                                   list_rm_true[i]/(pipe.d_int*np.pi),
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(r_i, 
                                   list_ri_true[i]/(pipe.d_int*np.pi),
                                   rtol=relative_tolerance)
                                   
        np.testing.assert_allclose(qs, 
                                   list_qs_true[i],
                                   rtol=relative_tolerance)
                                    
        np.testing.assert_allclose(qr, 
                                   list_qr_true[i],
                                   rtol=relative_tolerance)
                        
        #**********************************************************************
    
    #**************************************************************************
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_fic(fluiddb):
    
    # fluid speed
    
    fluid_speed = 1 # m/s
    
    # fluid
    
    fluid = fic.Fluid(phase='l',
                      temperature=273.15+60,
                      pressure=1e5,
                      db=fluiddb)
    
    # pipe
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=55,
                             e_eff=1e-5,
                             d_int=0.273-2*0.005,
                             d_ext=0.273,
                             d_ins=0.273,
                             d_cas=0.273,
                             k_ins=0.029,
                             k_cas=0.5)
    
    # heat transfer coefficient
    
    h = trenches.HeatTransferCoefficientInternalForcedConvection(
        pipe,
        fluid,
        fluid_speed)
    
    # assert h is positive
    
    assert h > 0
    
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2005_distribution_pipes_single(fluid_db):
    
    
    #**************************************************************************
    
    # trench
    
    pipe_distance = 0.73 # m
    
    pipe_depth = 1.28 # m
    
    h_gs = 14.6 # W/m2K
    
    ground_temperature = 8+273.15 # K
    
    soil_k = 1.5 # W/mK
    
    supply_temperature = 80+273.15
    
    return_temperature = 40+273.15
    
    #**************************************************************************
    
    # pipes
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=60,
                             e_eff=1e-5,
                             d_int=0.0889-2*0.0032,
                             d_ext=0.0889,
                             d_ins=0.1578,
                             d_cas=0.160,
                             k_ins=0.0265,
                             k_cas=0.43)
    
    #**************************************************************************
    
    u11_true = 0.2664 # W/mK
    
    u22_true = 0.2664 # W/mK
    
    u12_true = 0.0113 # W/mK
    
    q_total_true = 26.53 # W/m
    
    #**************************************************************************
    
    relative_tolerance = 0.01
    
    qt_u11 = 2*(u11_true-u12_true)*(
        (supply_temperature+return_temperature)*0.5-ground_temperature
        )
    
    qt_u22 = 2*(u22_true-u12_true)*(
        (supply_temperature+return_temperature)*0.5-ground_temperature
        )
                                    
    np.testing.assert_allclose(qt_u11, 
                               q_total_true,
                               rtol=relative_tolerance)
                                                           
    np.testing.assert_allclose(qt_u22,
                               q_total_true,
                               rtol=relative_tolerance)
    
    #**************************************************************************
    
    relative_tolerance = 0.0341
    
    qs_true = (
        (u11_true-u12_true)*(supply_temperature-ground_temperature)+
        u12_true*(supply_temperature-return_temperature)
        )
        
    qr_true = (
        (u22_true-u12_true)*(return_temperature-ground_temperature)+
        u12_true*(supply_temperature-return_temperature)
        )
                                                           
    np.testing.assert_allclose(qs_true+qr_true, 
                               q_total_true,
                               rtol=relative_tolerance) # Min.: 0.03408971
    
    #**************************************************************************
           
    relative_tolerance_qs = [0.036,0.036]
    relative_tolerance_qr = [0.128,0.128]
    relative_tolerance_qt = [0.033,0.033]
    relative_tolerance_u1122 = [0.038,0.038]
    relative_tolerance_u12 = [0.159,0.158]
    
    # calculations
    
    list_ground_resistance_models = [
        trenches.TRGTPT_MULTIPOLE_ZERO_ORDER,
        trenches.TRGTPT_MULTIPOLE_FIRST_ORDER
        ]
    
    for i, model in enumerate(list_ground_resistance_models):
    
        (rsym,
         rasym) = trenches.ThermalResistanceTwoBuriedSinglePipesWallenten(
            pipe,
            soil_k,
            pipe_depth,
            pipe_distance,
            h_gs,
            model=model)
             
        (qs,
         qr) = trenches.HeatLossesSupplyReturnPipesSymmetricalAntiSymmetrical(
            supply_temperature,
            return_temperature,
            ground_temperature,
            rsym,
            rasym) 
             
             
        (u1122,
         u12) = trenches.HeatTransferCoefficientsFromSymmetricalAsymmetricalResistances(
              rsym, rasym)
    
        # u1122 = 0.5*(1/rsym+1/rasym)
        
        # u12 = 0.5*(1/rasym-1/rsym)
                  
        np.testing.assert_allclose(qs+qr, 
                                   q_total_true,
                                   rtol=relative_tolerance_qt[i])
                            
        np.testing.assert_allclose(qs, 
                                   qs_true,
                                   rtol=relative_tolerance_qs[i])
                                                                                          
        np.testing.assert_allclose(qr, 
                                   qr_true,
                                   rtol=relative_tolerance_qr[i])
                                                                                          
        np.testing.assert_allclose(u12, 
                                   u12_true,
                                   rtol=relative_tolerance_u12[i])
                                                                                          
        np.testing.assert_allclose(u1122, 
                                   u11_true,
                                   rtol=relative_tolerance_u1122[i])
    
    #**************************************************************************
           
    relative_tolerance_qs = [0.02,0.02,0.02]
    relative_tolerance_qr = [0.111,0.111,0.112]
    relative_tolerance_qt = [0.02,0.02,0.02]
    relative_tolerance_u1122 = [0.02,0.02,0.02]
    relative_tolerance_u12 = [0.124,0.124,0.125]
        
    # calculations
    
    ground_resistance_models = [
        trenches.TRGTPT_KRISCHER1936,
        trenches.TRGTPT_MULTIPOLE_ZERO_ORDER,
        trenches.TRGTPT_MULTIPOLE_FIRST_ORDER]
    
    for i, model in enumerate(ground_resistance_models):
    
        (u1122, # u1 in Bohm2000
         u12,   # u2 in Bohm2000
         r_g,
         r_i,
         r_m) = trenches.HeatTransferCoefficientsTwoBuriedSingles(
            pipe,
            pipe_depth,
            pipe_distance,
            soil_k,
            h_gs,
            np.inf,
            model=model)
             
           
        qs, qr = trenches.HeatLossesBuriedSupplyReturnPipesDirect(
            supply_temperature,
            return_temperature,
            ground_temperature,
            u1122, 
            u12)
                                               
        np.testing.assert_allclose(qs+qr, 
                                   q_total_true,
                                   rtol=relative_tolerance_qt[i])
                            
        np.testing.assert_allclose(qs, 
                                   qs_true,
                                   rtol=relative_tolerance_qs[i])
                                                                                          
        np.testing.assert_allclose(qr, 
                                   qr_true,
                                   rtol=relative_tolerance_qr[i])
                                                                                          
        np.testing.assert_allclose(u1122, 
                                   u11_true,
                                   rtol=relative_tolerance_u1122[i])
                                                                                          
        np.testing.assert_allclose(u12, 
                                   u12_true,
                                   rtol=relative_tolerance_u12[i])
        
    #**************************************************************************
        
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_bohm2005_distribution_pipes_twin(fluid_db):
    
    #**************************************************************************
    
    # trench
    
    pipe_distance = 0.0251+0.0889 # m
    
    pipe_depth = 1.28 # m
    
    h_gs = 14.6 # W/m2K
    
    ground_temperature = 8+273.15 # K
    
    soil_k = 1.5 # W/mK
    
    supply_temperature = 80+273.15
    
    return_temperature = 40+273.15
    
    #**************************************************************************
    
    # pipes
    
    twin_pipe = InsulatedTwinPipe(length=1000,
                                  k=60,
                                  e_eff=1e-5,
                                  d_int=0.0889-2*0.0032,
                                  d_ext=0.0889,
                                  d_ins=0.2483,
                                  d_cas=0.2483+2*0.0036,
                                  k_ins=0.0265,
                                  k_cas=0.43,
                                  pipe_center_distance=pipe_distance)
    
    #**************************************************************************
    
    u11_true = 0.2517 # W/mK
    
    u22_true = 0.2534 # W/mK
    
    u12_true = 0.0784 # W/mK
    
    q_total_true = 18.08 # W/m
    
    qs_true = (
        (u11_true-u12_true)*(supply_temperature-ground_temperature)+
        u12_true*(supply_temperature-return_temperature)
        )
        
    qr_true = (
        (u22_true-u12_true)*(return_temperature-ground_temperature)+
        u12_true*(supply_temperature-return_temperature)
        )
    
    #**************************************************************************
    
    relative_tolerance = 0.01
    
    qt_u11 = 2*(u11_true-u12_true)*(
        (supply_temperature+return_temperature)*0.5-ground_temperature
        )
    
    qt_u22 = 2*(u22_true-u12_true)*(
        (supply_temperature+return_temperature)*0.5-ground_temperature
        )
                                    
    np.testing.assert_allclose(qt_u11, 
                               q_total_true,
                               rtol=relative_tolerance)
                                                           
    np.testing.assert_allclose(qt_u22,
                               q_total_true,
                               rtol=relative_tolerance)
    
    #**************************************************************************
    
    # relative_tolerance = 0.01
                                                           
    # # np.testing.assert_allclose(qs_true, 
    # #                             q_total_true,
    # #                             rtol=relative_tolerance) # Min.: 0.03408971
                                                                                   
    # # np.testing.assert_allclose(qr_true, 
    # #                             q_total_true,
    # #                             rtol=relative_tolerance) # Min.: 0.03408971
                                                                                   
    # np.testing.assert_allclose(qs_true+qr_true, 
    #                             q_total_true,
    #                             rtol=relative_tolerance) # Min.: 0.03408971
    
    #**************************************************************************
           
    relative_tolerance_qt = [0.057,0.228,0.12,0.055]
    relative_tolerance_qs = [0.167,0.036,0.05]
    relative_tolerance_qr = [0.128,0.128,0.05]
    relative_tolerance_u1122 = [0.141,0.038,0.05]
    relative_tolerance_u12 = [0.159,0.158,0.05]
    
    # calculations
    
    list_ground_resistance_models = [
        trenches.TRGTPT_TWO_MODEL_APPROX,
        trenches.TRGTPT_MULTIPOLE_ZERO_ORDER,
        trenches.TRGTPT_MULTIPOLE_FIRST_ORDER
        ]
    
    for i, model in enumerate(list_ground_resistance_models):
    
        (rsym,
         rasym) = trenches.ThermalResistanceBuriedTwinPipesWallenten(
            twin_pipe,
            soil_k,
            pipe_depth,
            pipe_distance,
            h_gs,
            model=model)
             
        #********************************************************************** 
             
        (qs,
         qr) = trenches.HeatLossesSupplyReturnPipesSymmetricalAntiSymmetrical(
            supply_temperature,
            return_temperature,
            ground_temperature,
            rsym,
            rasym)
             
        #**********************************************************************
    
        # TODO: verify module again and remove these instructions
        # print('hey')
        # print('(rsym,rasym)')
        # print((rsym,rasym))
        # print('(qs,qr)')
        # print((qs,qr))
        # print('qs+qr')
        # print(qs+qr)
        #print((u1122,u12))
                  
        np.testing.assert_allclose(qs+qr, 
                                   q_total_true,
                                   rtol=relative_tolerance_qt[i])
                                    
        # np.testing.assert_allclose(qs, 
        #                            qs_true,
        #                            rtol=relative_tolerance_qs[i])
                                                                                          
        # np.testing.assert_allclose(qr, 
        #                            qr_true,
        #                            rtol=relative_tolerance_qr[i])
                                                                                          
        # np.testing.assert_allclose(u12, 
        #                            u12_true,
        #                            rtol=relative_tolerance_u12[i])
                                                                     
        # np.testing.assert_allclose(u1122, 
        #                            u11_true,
        #                            rtol=relative_tolerance_u1122[i])
                                                                                                             
        # np.testing.assert_allclose(u1122, 
        #                            u22_true,
        #                            rtol=relative_tolerance_u1122[i])
    
    #**************************************************************************
        
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************

def example_unknown_models():
        
    # trench
    
    pipe_distance = 0.0251+0.0889 # m
    
    pipe_depth = 1.28 # m
    
    h_gs = 14.6 # W/m2K
    
    soil_k = 1.5 # W/mK
    
    # supply_temperature = 80+273.15
    
    # return_temperature = 40+273.15
    
    # ground_temperature = 8+273.15 # K
    
    #**************************************************************************
    
    # pipes
    
    twin_pipe = InsulatedTwinPipe(length=1000,
                                  k=60,
                                  e_eff=1e-5,
                                  d_int=0.0889-2*0.0032,
                                  d_ext=0.0889,
                                  d_ins=0.2483,
                                  d_cas=0.2483+2*0.0036,
                                  k_ins=0.0265,
                                  k_cas=0.43,
                                  pipe_center_distance=pipe_distance)
    
    try:
        
        (rsym,
         rasym) = trenches.ThermalResistanceBuriedTwinPipesWallenten(
            twin_pipe,
            soil_k,
            pipe_depth,
            pipe_distance,
            h_gs,
            model='thismodeldoesnotexist')
    
    except NotImplementedError:
        
        assert True
        
    #**************************************************************************
    
    # pipes
    
    pipe = fic.InsulatedPipe(length=1000,
                             k=60,
                             e_eff=1e-5,
                             d_int=0.0889-2*0.0032,
                             d_ext=0.0889,
                             d_ins=0.1578,
                             d_cas=0.160,
                             k_ins=0.0265,
                             k_cas=0.43)
                             
    #**************************************************************************
    
    try:
        
        (_,
         _) = trenches.ThermalResistanceTwoBuriedSinglePipesWallenten(
            pipe,
            soil_k,
            pipe_depth,
            pipe_distance,
            h_gs,
            model='thismodeldoesnotexisteither')
    
    except NotImplementedError:
        
        assert True
        
    #**************************************************************************
        
    try:
        
        (_, 
         _,
         _,
         _,
         _) = trenches.HeatTransferCoefficientsTwoBuriedSingles(
            pipe,
            pipe_depth,
            pipe_distance,
            soil_k,
            h_gs,
            np.inf,
            model='nordoesthisoneexist')
             
    except NotImplementedError:
        
        assert True
        
    #**************************************************************************
        
    try:
        
        _ = trenches.ThermalResistanceBuriedSinglePipeWallenten(
            pipe,
            soil_k,
            pipe_depth,
            h_gs,
            model='yetanotherunknownmodel')
        
    except NotImplementedError:
        
        assert True
                                     
    #**************************************************************************
        
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************
#******************************************************************************